import matrix.ArrayListMatrix;
import org.apache.log4j.Logger;

import java.io.*;
import java.util.ArrayList;
import java.util.Map;
import java.util.SortedMap;

/**
 * Created by aleks_000 on 14.12.13.
 */
public class Program {
    private static final BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
    private static final Logger LOGGER = Logger.getLogger(Program.class);


    public static void main(String[] args) {

        try{
            while (true) {
                System.out.println("analyze: analyze a file");
                System.out.println("write-matrix: write random matrix in the file");
                System.out.println("read-matrix: read matrix from the file");
                System.out.println("serialize-matrix: serialize random matrix");
                System.out.println("deserialize-matrix: deserialize matrix from file");
                System.out.println("exit: close app");
                String cmd = consoleReader.readLine();
                if (cmd.equalsIgnoreCase("exit")) {
                    break;
                }
                if (cmd.equalsIgnoreCase("analyze")) {
                    analyzeText();
                    System.out.println();
                    continue;
                }
                if (cmd.equalsIgnoreCase("write-matrix")){
                    writeMatrix();
                    System.out.println();
                    continue;
                }
                if (cmd.equalsIgnoreCase("read-matrix")) {
                    readMatrix();
                    System.out.println();
                    continue;
                }
                if (cmd.equalsIgnoreCase("serialize-matrix")){
                    serializeMatrix();
                    System.out.println();
                    continue;
                }
                if (cmd.equalsIgnoreCase("deserialize-matrix")) {
                    deserializeMatrix();
                    System.out.println();
                    continue;
                }
                System.out.println("Incorrect command. Try again");
            }
            consoleReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // todo: add a logic for exception handling
    private static void analyzeText() {
        System.out.print("Enter filename: ");
        String filename = null;

        try {
            filename = consoleReader.readLine();
            CharStatisticsAnalyzer statisticsAnalyzer = new CharStatisticsAnalyzer();
            SortedMap<Character, Double> result = statisticsAnalyzer.analyze(filename);
            final String format = "Character %c (%d): %f percents";
            for (Map.Entry<Character, Double> entry : result.entrySet()) {
                System.out.println(String.format(format, new Object[] {entry.getKey(), (int) entry.getKey(), entry.getValue() * 100}));
            }
        } catch (IOException e) {
            System.out.println("Can't open selected file. Try later.");
            LOGGER.error(String.format("Can't found entered file: %s", filename));
        }
    }

    // todo: add a logic for exception handling
    private static void writeMatrix()  {
        System.out.print("Enter a size of the matrix: ");
        int size = 0;
        String filename = null;
        try {
            size = Integer.parseInt(consoleReader.readLine());
            ArrayListMatrix matrix = ArrayListMatrix.createRandom(size, size);
            System.out.print("Enter a destination filename: ");
            filename = consoleReader.readLine();
            FileWriter writer = new FileWriter(filename);
            writer.write(matrix.toString());
            writer.close();
        } catch (IOException e) {
            System.out.printf("Can't create file");
            LOGGER.error(e.getMessage());
        }
    }

    // todo: add a logic for exception handling
    private static void readMatrix() {
        try {
            System.out.print("Enter filename: ");
            String filename = consoleReader.readLine();
            FileReader reader = new FileReader(filename);
            BufferedReader bufferedReader = new BufferedReader(reader);
            String matrixStr = bufferedReader.readLine();
            if (matrixStr != null) {
                ArrayListMatrix parsedMatrix = ArrayListMatrix.parse(matrixStr);
                System.out.println("Parsed matrix:");
                System.out.println(parsedMatrix.toString());
            }
            bufferedReader.close();
            reader.close();
        } catch (IOException ex) {

            System.out.println("File not found");
        }

    }

    // todo: add a logic for exception handling
    private static void serializeMatrix() {
        try {
            System.out.print("Enter size of the matrix: ");
            int size = Integer.parseInt(consoleReader.readLine());
            ArrayListMatrix matrix = ArrayListMatrix.createRandom(size, size);
            System.out.print("Enter filename: ");
            String filename = consoleReader.readLine();
            FileOutputStream fileInputStream = new FileOutputStream(filename);
            ObjectOutputStream objectInputStream = new ObjectOutputStream(fileInputStream);
            objectInputStream.writeObject(matrix);
            objectInputStream.close();
            System.out.println(String.format("Matrix successfully serialized in file %s", filename));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    // todo: add a logic for exception handling
    private static void deserializeMatrix() {
        try {
            System.out.print("Enter filename: ");
            String filename = consoleReader.readLine();
            FileInputStream fileInputStream = new FileInputStream(filename);
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            ArrayListMatrix matrix = (ArrayListMatrix) objectInputStream.readObject();
            objectInputStream.close();
            System.out.println("Matrix successfully restored.");
            System.out.println("Restored matrix:");
            System.out.println(matrix.toString());
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
    }
}

